#pragma once
#include <iostream>
#include <string>
#include <string.h>
#include <assert.h>
#include <vector>
#include "reverse_iterator.hpp"
using namespace std;

namespace bit
{
    template<class T>
    class vector
    {
    public:
        // Vector的迭代器是一个原生指针
        typedef T* iterator;
        typedef const T* const_iterator;
        typedef Reverse_iterator<iterator,T&,T*> reverse_iterator;
        typedef Reverse_iterator<iterator,const T&,const T*> const_reverse_iterator;

        iterator begin() { return _start; }
        iterator end() { return _finish; }
        const_iterator cbegin()const { return _start; }
        const_iterator cend()const { return _finish; }

        reverse_iterator rbegin() { return reverse_iterator(end()); }
        reverse_iterator rend() { return reverse_iterator(begin()); }
        // const_reverse_iterator rcbegin()const { return reverse_iterator(end()); }
        // const_reverse_iterator rcend()const { return reverse_iterator(begin()); }

        // construct and destroy
        vector() :_start(nullptr), _finish(nullptr), _endofstorage(nullptr) {}
        vector(int n, const T& value = T());

        template<class InputIterator>
        vector(InputIterator first, InputIterator last);

        vector(const vector<T>& v);
        vector<T>& operator= (vector<T> v);

        ~vector() 
        {
            delete[] _start; 
            _finish = nullptr;
            _endofstorage = nullptr;
        }
        // capacity
        size_t size() const { return _finish - _start; }
        size_t capacity() const { return _endofstorage - _start; }
        void reserve(size_t n);
        void resize(size_t n, const T& value = T());
        ///////////////access///////////////////////////////
        T& operator[](size_t pos) { return _start[pos]; }
        const T& operator[](size_t pos)const { return _start[pos]; }
        ///////////////modify/////////////////////////////
        void push_back(const T& x);
        void pop_back();
        void swap(vector<T>& v);
        iterator insert(iterator pos, const T& x);
        iterator erase(iterator pos);
    private:
        iterator _start = nullptr; // 指向数据块的开始
        iterator _finish = nullptr; // 指向有效数据的尾
        iterator _endofstorage = nullptr; // 指向存储容量的尾
    };

    template<class T>
    vector<T>::vector(int n, const T& value)
    {
        reserve(n);
        for (int i = 0; i < n; i++)
        {
            push_back(value);
        }
    }

    template<class T>
    template<class InputIterator>
    vector<T>::vector(InputIterator first, InputIterator last)
    {
        while (first != last)
        {
            push_back(*first);
            first++;
        }
    }

    template<class T>
    vector<T>::vector(const vector<T>& v)
    {
        reserve(v.capacity());
        int i = 0;
        while (i < v.size())
        {
            push_back(v[i]);
            i++;
        }
    }

    template<class T>
    vector<T>& vector<T>::operator= (vector<T> v)
    {
        swap(v);
        return *this;
    }

    template<class T>
    void vector<T>::reserve(size_t n)
    {
        size_t oldsize = size();
        if (n > capacity())
        {
            iterator temp = new T[n];
            size_t begin = 0;
            while (begin < oldsize)
            {
                temp[begin] = _start[begin];
                begin++;
            }
            delete[] _start;
            _start = temp;
            _finish = _start + oldsize;
            _endofstorage = _start + n;
        }
    }

    template<class T>
    void vector<T>::resize(size_t n, const T& value)
    {
        if (n > capacity())
        {
            reserve(n);
            while (_finish != _endofstorage)
            { 
                push_back(value);
            }
        }
        else//删除数据
        {
            _finish = _start + n;
        }
    }

    template<class T>
    void vector<T>::push_back(const T& x)
    {
        if (_finish == _endofstorage)
        {
            int newcapacity = size() == 0 ? 4 : size() * 2;
            reserve(newcapacity);
        }
        _start[size()] = x;
        _finish++;
    }

    template<class T>
    void vector<T>::pop_back()
    {
        _finish--;
    }

    template<class T>
    void vector<T>::swap(vector<T>& v)
    {
        std::swap(_start,v._start);
        std::swap(_finish, v._finish);
        std::swap(_endofstorage, v._endofstorage);
    }

    template<class T>
    T* vector<T>::insert(iterator pos, const T& x)
    {
        assert(pos >= _start && pos <= _finish);
        
        if (_start == _finish)
        {
            int i = pos - _start;
            int newcapacity = size() == 0 ? 4 : size() * 2;
            reserve(newcapacity);
            pos = _start + i;
        }
        iterator cur = pos;
        while (cur != _finish)
        {
            *(cur + 1) = *cur;
            cur++;
        }
        *pos = x;
        _finish++;
        return pos;
    }

    template<class T>
    T* vector<T>::erase(iterator pos)
    {
        iterator cur = pos;
        while (cur != _finish)
        {
            *cur = *(cur + 1);
            cur++;
        }
        _finish--;
        return pos;
    }

    // void test()
    // {
    //     vector<int> v1;
    //     v1.push_back(1);
    //     v1.push_back(2);
    //     v1.push_back(3);
    //     v1.push_back(4);
    //     v1.push_back(5);
    //     v1.push_back(6);
    //     v1.push_back(7);
    //     v1.push_back(8);
    //     v1.push_back(9);
    //     v1.erase(v1.end());
    //     for (auto e : v1)
    //     {
    //         cout << e << ' ';
    //     }
    //     cout << endl;
    //     //vector<string> v1(10, "hello");
    //     //v1.resize(5);
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';
    //     //}
    //     //cout << endl;
    //     //v1.insert(v1.end()-3, "bit");
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';
    //     //}
    //     //cout << endl;
    //     //vector<string> v2(4, "bit");
    //     //v1 = v2;
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';
    //     //}
    //     //cout << endl;


    //     //vector<string> v1(10, "hello");
    //     //vector<string> v2(v1);
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';
    //     //}
    //     //cout << endl;
    //     //int arr[] = {1,2,3,4,5,6,7,8,9,10};
    //     //string s1("ahello world");
    //     //vector<int> v1(s1.begin(),s1.end());
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';
    //     //}
    //     //cout << endl;
    //     //vector<int> v1(10,2);
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';
    //     //}
    //     //cout << endl;
    //     //std::vector<int> v1(10, 1);
    //     //   
    //     //for (auto e : v1)
    //     //{
    //     //    cout << e << ' ';

    //     //}
    //     //cout << endl;
    //     //vector<int> v1;
    //     //for (int i = 1; i <= 500; i++)
    //     //{
    //     //    v1.push_back(i);
    //     //}
    //     //cout << v1[5] << endl;
    // }
}



